
var board = new Array();
var score = 0;
var hasConflicted = new Array();

$(document).ready(function(){
    newgame();
});

function newgame(){
    //初始化棋盘格
    init();

    //在随机两个格子生成数字
    generateOneNumber();
    generateOneNumber();
}

function init(){
    for( var i = 0 ; i < 4 ; i ++ )
        for( var j = 0 ; j < 4 ; j ++ ){
            // 获取网格中每个格子
            var gridCell = $('#grid-cell-'+i+"-"+j); 

            // 初始化每个格子的位置
            gridCell.css('top', getPosTop( i , j ) ); 
            gridCell.css('left', getPosLeft( i , j ) );
        }

    for( var i = 0 ; i < 4 ; i ++ ){
        board[i] = new Array(); // 做成二维数组
        hasConflicted[i] = new Array();
        for( var j = 0 ; j < 4 ; j ++ ){
            // 初始化每个格子数字为0
            board[i][j] = 0;

            // 初始化设置每个格子上都未有数字
            hasConflicted[i][j] = false;
        }
    }
    
    updateBoardView();
    
    score = 0;
}

function updateBoardView(){ //更新格子视图

    $(".number-cell").remove();

    for( var i = 0 ; i < 4 ; i ++ )
        for( var j = 0 ; j < 4 ; j ++ ){
            $("#grid-container").append( '<div class="number-cell" id="number-cell-'+i+'-'+j+'"></div>' );
            var theNumberCell = $('#number-cell-'+i+'-'+j);
            
            // 当前格子为空时
            if( board[i][j] == 0 ){ 
                theNumberCell.css('width','0px');
                theNumberCell.css('height','0px');
                theNumberCell.css('top',getPosTop(i,j) + 50 );
                theNumberCell.css('left',getPosLeft(i,j) + 50 );
            }
            // 当前格子不为空时
            else{ 
                theNumberCell.css('width','100px');
                theNumberCell.css('height','100px');
                theNumberCell.css('top',getPosTop(i,j));
                theNumberCell.css('left',getPosLeft(i,j));
                theNumberCell.css('background-color',getNumberBackgroundColor( board[i][j] ) );
                theNumberCell.css('color',getNumberColor( board[i][j] ) );
                theNumberCell.text( board[i][j] );
            }

            hasConflicted[i][j] = false;
        }
}

function generateOneNumber(){ // 在随机一个格子产生一个随机的数字

    // 随机生成数字前先判断网格还有无空的格子
    if( nospace( board ) )
        return false;

    // 随机一个位置
    var randx = parseInt( Math.floor( Math.random() * 4 ) );
    var randy = parseInt( Math.floor( Math.random() * 4 ) );

    // while(true) {
    //     if (board[randx][randy] == 0)
    //         break;

    //     randx = parseInt( Math.floor( Math.random()  * 4 ) );
    //     randy = parseInt( Math.floor( Math.random()  * 4 ) );
    // }

    var times = 0;
    while( times < 50 ){
        if( board[randx][randy] == 0 )
            break;

        randx = parseInt( Math.floor( Math.random()  * 4 ) );
        randy = parseInt( Math.floor( Math.random()  * 4 ) );

        times ++;
    }
    // 循环50次随机位置还未找到空格子，则手动查找空格子
    while (times == 50) {
        for( var i = 0 ; i < 4 ; i ++ )
            for( var j = 0 ; j < 4 ; j ++ ) 
                if (board[i][j] == 0) {
                    randx = i;
                    randy = j;
                }
    }

    // 随机生成一个数字：2 或 4
    var randNumber = Math.random() < 0.5 ? 2 : 4;

    // 在随机位置显示随机数字
    board[randx][randy] = randNumber;
    // 加入数字产生动画效果
    showNumberWithAnimation( randx , randy , randNumber );

    return true;
}

$(document).keydown( function( event ){ // 定义用户按键产生的结果
    switch( event.which ){
        case 37: //left
            if( moveLeft() ){
                setTimeout("generateOneNumber()", 210);

                // 每次移动后判断游戏是否结束
                setTimeout("isgameover()", 300);
            }
            break;
        case 38: //up
            if( moveUp() ){
                setTimeout("generateOneNumber()", 210);
                setTimeout("isgameover()", 300);
            }
            break;
        case 39: //right
            if( moveRight() ){
                setTimeout("generateOneNumber()", 210);
                setTimeout("isgameover()", 300);
            }
            break;
        case 40: //down
            if( moveDown() ){
                setTimeout("generateOneNumber()", 210);
                setTimeout("isgameover()", 300);
            }
            break;
        default: //default
            break;
    }
});

function isgameover(){ // 判断游戏是否结束
    // 网格没有空格子&所有格子不能移动时，游戏结束
    if (nospace(board) && nomove(board)) 
        gameover();
    
}

function gameover() { // 弹出游戏结束并显示得分
    alert(`Game Over!
    Score:${score}`);
}

function moveLeft(){ //向左移动逻辑

    // 判断网格中是否还能向左移动
    if( !canMoveLeft( board ) )
        return false;

    //moveLeft
    for( var i = 0 ; i < 4 ; i ++ )
        for( var j = 1 ; j < 4 ; j ++ ){
            if( board[i][j] != 0 ){

                for( var k = 0 ; k < j ; k ++ ){
                    //左边落脚位置没有数字 且 移动路径没有障碍时
                    if( board[i][k] == 0 && noBlockHorizontal( i , k , j , board ) ){ 
                        //move
                        showMoveAnimation( i , j , i , k );
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    //左边落脚位置数字等于待判定元素数字 且 移动路径没有障碍时
                    else if( board[i][k] == board[i][j] && noBlockHorizontal( i , k , j , board ) && !hasConflicted[i][k] ){ 
                        //move
                        showMoveAnimation( i , j , i , k );
                        //add
                        board[i][k] += board[i][j];
                        board[i][j] = 0;
                        //add score
                        score += board[i][k];
                        updateScore(score);

                        hasConflicted[i][k] = true;
                        continue;
                    }
                }
            }
        }

    setTimeout("updateBoardView()",200);
    return true;
}

function moveRight() { //向右移动逻辑
    if (!canMoveRight(board))
        return false;

    for( var i = 0 ; i < 4 ; i ++ )
        for( var j = 2 ; j >= 0 ; j -- ) {
            if( board[i][j] != 0 ){
                for( var k = 3 ; k > j ; k -- ){

                    if( board[i][k] == 0 && noBlockHorizontal( i , j , k , board ) ){
                        //move
                        showMoveAnimation( i , j , i , k );
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    else if( board[i][k] == board[i][j] && noBlockHorizontal( i , j , k , board ) && !hasConflicted[i][k] ){
                        //move
                        showMoveAnimation( i , j , i , k );
                        //add
                        board[i][k] *= 2;
                        board[i][j] = 0;
                        //addscore
                        score += board[i][k];
                        updateScore(score);

                        hasConflicted[i][k] = true;
                        continue;
                    }
                }
            }
        }
        
    setTimeout("updateBoardView()",200);
    return true;
}   

function moveUp() { //向上移动逻辑
    if (!canMoveUp(board))
        return false;
    
    //moveUp
    for( var j = 0 ; j < 4 ; j ++ )
        for( var i = 1 ; i < 4 ; i ++ ) {
            if( board[i][j] != 0 ) {
                for (var k = 0 ; k < i ; k ++) {

                    if (board[k][j] == 0 && noBlockVertical( j , k , i , board )) {
                        //move
                        showMoveAnimation( i , j , k , j );
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    else if( board[k][j] == board[i][j] && noBlockVertical( j , k , i , board ) && !hasConflicted[k][j] ) {
                        //move
                        showMoveAnimation( i , j , k , j );
                        //add
                        board[k][j] *= 2;
                        board[i][j] = 0;
                        //addscore
                        score += board[k][j];
                        updateScore(score);

                        hasConflicted[k][j] = true;
                        continue;
                    }
                }
            }
        }

    setTimeout("updateBoardView()",200);
    return true;        
}

function moveDown() { //向下移动逻辑
    if (!canMoveDown(board))
        return false;
    
    for( var j = 0 ; j < 4 ; j ++ )
        for( var i = 2 ; i >= 0 ; i -- ) {
            if( board[i][j] != 0 ) {
                for (var k = 3 ; k > i ; k --) {

                    if (board[k][j] == 0 && noBlockVertical( j , i , k , board )) {
                        //move
                        showMoveAnimation( i , j , k , j );
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    else if( board[k][j] == board[i][j] && noBlockVertical( j , i , k , board ) && !hasConflicted[k][j] ) {
                        //move
                        showMoveAnimation( i , j , k , j );
                        //add
                        board[k][j] *= 2;
                        board[i][j] = 0;
                        //addscore
                        score += board[k][j];
                        updateScore(score);

                        hasConflicted[k][j] = true;
                        continue;
                    }
                }
            }
        }

    setTimeout("updateBoardView()",200);
    return true; 
}